package top.blueShark.template.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import top.blueShark.template.entity.SysMenu;
import top.blueShark.template.mapper.SysMenuMapper;
import top.blueShark.template.service.SysMenuService;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

@Service
public class SysMenuServiceImpl implements SysMenuService {

	private static final Logger logger = LoggerFactory.getLogger(SysMenuServiceImpl.class);

	@Resource
	private SysMenuMapper sysMenuMapper;

	@Override
	public List<SysMenu> getMenuTree() {
		List<SysMenu> allMenus = sysMenuMapper.selectAllMenu();
		return buildMenuTree(allMenus, 0);
	}

	@Override
	public List<SysMenu> getRoleMenuTree(List<String> ids) {
		List<SysMenu> allMenus = sysMenuMapper.selectRoleMenu(ids);
		return buildMenuTree(allMenus, 0);
	}

	private List<SysMenu> buildMenuTree(List<SysMenu> menuList, Integer pid) {
		List<SysMenu> tree = new ArrayList<>();
		ObjectMapper objectMapper = new ObjectMapper();
		for (SysMenu menu : menuList) {
			// 反序列化 metaJson 到 meta 字段
			if (menu.getMetaJson() != null) {
				try {
					Map<String, Object> meta = objectMapper.readValue(
						menu.getMetaJson(),
						new com.fasterxml.jackson.core.type.TypeReference<Map<String, Object>>() {}
					);
					menu.setMeta(meta);
				} catch (Exception e) {
					logger.error("metaJson 反序列化失败", e);
					menu.setMeta(new HashMap<>()); // 保证前端有 meta 字段
				}
			} else {
				// 没有 metaJson 也要补一个 meta 字段，至少包含 title、icon
				Map<String, Object> meta = new HashMap<>();
				meta.put("title", menu.getName());
				meta.put("icon", menu.getIcon());
				menu.setMeta(meta);
			}
			if ((pid == null && (menu.getPid() == null || menu.getPid() == 0))
					|| (pid != null && pid.equals(menu.getPid()))) {
				menu.setChildren(buildMenuTree(menuList, menu.getId()));
				tree.add(menu);
			}
		}
		return tree;
	}

	@Override
	public boolean pathExists(String path, Integer id) {
		return sysMenuMapper.countByPath(path, id) > 0;
	}

	@Override
	public boolean nameExists(String name, Integer id) {
		return sysMenuMapper.countByName(name, id) > 0;
	}

	@Override
	public void addMenu(SysMenu menu) {
		logger.info("添加菜单，名称：{}，路径：{}", menu.getName(), menu.getPath());
		sysMenuMapper.insertMenu(menu);
	}

	@Override
	public void updateMenu(SysMenu menu) {
		logger.info("更新菜单，id：{}，名称：{}，路径：{}", menu.getId(), menu.getName(), menu.getPath());
		sysMenuMapper.updateMenu(menu);
	}

	@Override
	public void deleteMenu(Integer id) {
		logger.info("删除菜单及其所有子菜单，id: {}", id);
		// 递归查找所有子菜单 id
		List<Integer> allIds = new ArrayList<>();
		collectAllMenuIds(id, allIds);
		// 先批量删除所有菜单在 sys_role_menu 里的关联
		for (Integer menuId : allIds) {
			sysMenuMapper.deleteRoleMenuByMenuId(menuId);
		}
		// 再批量删除菜单本身
		for (Integer menuId : allIds) {
			sysMenuMapper.deleteMenuById(menuId);
		}
	}

	/**
	 * 递归收集所有子菜单 id（包括自身）
	 */
	private void collectAllMenuIds(Integer id, List<Integer> idList) {
		idList.add(id);
		List<SysMenu> children = sysMenuMapper.selectByPid(id);
		for (SysMenu child : children) {
			collectAllMenuIds(child.getId(), idList);
		}
	}

}